

#include <jni.h>
#include <matrix.h>
#include <stdlib.h>

#include <stdio.h>

/* Some function defs... */

void      vm_matrix_to_jdouble(JNIEnv *env, jdoubleArray m, vm_matrix *mat);
vm_matrix vm_jdouble_to_matrix(JNIEnv *env, jdoubleArray m, jint rows);


vm_matrix vm_jdouble_to_matrix(JNIEnv *env, jdoubleArray m, jint rows){

  vm_matrix mat;
  int array_len = (*env)->GetArrayLength(env, m);
  //fprintf(stderr, "[vm_jdouble_to_matrix] Array length: %d\n", array_len);
  int columns = array_len / (int) rows;
  //fprintf(stderr, "[vm_jdouble_to_matrix] Rows: %d; Columns: %d\n", 
          //rows, columns);
  double *data = (*env)->GetDoubleArrayElements(env, m, NULL);

  /* Now build the matrix struct to use this data... */
  double **rows_array = (double **)malloc(sizeof(double *) * rows);

  int i = 0;
  for ( ; i < rows; i++){
    rows_array[i] = data + (columns * i);
  }

  mat.data = rows_array;
  mat.rows = rows;
  mat.columns = columns;
  return mat;

}

void vm_matrix_to_jdouble(JNIEnv *env, jdoubleArray m, vm_matrix *mat){

  double *data = (*env)->GetDoubleArrayElements(env, m, NULL);
  int rows, cols, offset = 0;
  for ( rows = 0; rows < mat->rows; rows++){
    for ( cols = 0; cols < mat->columns; cols++){
      data[offset++] = mat->data[rows][cols];
    }
  }
  (*env)->ReleaseDoubleArrayElements(env, m, data, 0);

}

void vm_free_jdouble_matrix(JNIEnv *env, jdoubleArray ary, vm_matrix *mat){

  (*env)->ReleaseDoubleArrayElements(env, ary, mat->data[0], 0);
  free((void *)mat->data);

}
